"""
支持属性访问的JSON对象类
"""

from typing import Any, Dict, List, Union, Iterator
import json
from .logger import setup_logger

logger = setup_logger("driver.utils")


class JsonObject:
    """
    支持属性访问的JSON对象类
    可以通过属性访问方式访问JSON数据，例如 obj.property 而不是 obj['property']
    同时也支持字典方式访问，例如 obj['property']
    """

    def __init__(self, data: Union[Dict[str, Any], List[Any], Any] = None):
        """
        初始化JsonObject

        Args:
            data: JSON数据，可以是字典、列表或其他JSON兼容的数据类型
        """
        if data is None:
            data = {}
        self._data = data
        self._convert_nested_objects()

    def _convert_nested_objects(self):
        """递归转换嵌套的对象为JsonObject"""
        if isinstance(self._data, dict):
            for key, value in self._data.items():
                if isinstance(value, dict):
                    self._data[key] = JsonObject(value)
                elif isinstance(value, list):
                    self._data[key] = self._convert_list(value)
        elif isinstance(self._data, list):
            self._data = self._convert_list(self._data)

    def _convert_list(self, data_list: List[Any]) -> List[Any]:
        """
        转换列表中的嵌套对象

        Args:
            data_list: 列表数据

        Returns:
            转换后的列表
        """
        converted_list = []
        for item in data_list:
            if isinstance(item, dict):
                converted_list.append(JsonObject(item))
            elif isinstance(item, list):
                converted_list.append(self._convert_list(item))
            else:
                converted_list.append(item)
        return converted_list

    def __getattr__(self, name: str) -> Any:
        """
        支持通过属性访问获取数据

        Args:
            name: 属性名

        Returns:
            属性值

        Raises:
            AttributeError: 当属性不存在时
        """
        if isinstance(self._data, dict) and name in self._data:
            return self._data[name]
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")

    def __setattr__(self, name: str, value: Any) -> None:
        """
        支持通过属性访问设置数据

        Args:
            name: 属性名
            value: 属性值
        """
        if name.startswith('_'):
            # 私有属性直接设置
            super().__setattr__(name, value)
        else:
            # 公共属性存储在_data中
            if not hasattr(self, '_data'):
                super().__setattr__('_data', {})
            if isinstance(self._data, dict):
                self._data[name] = value
            else:
                raise AttributeError(f"Cannot set attribute '{name}' on non-dict object. Current data type: {type(self._data)}")

    def __getitem__(self, key: Union[str, int]) -> Any:
        """
        支持通过索引访问获取数据（字典方式访问）

        Args:
            key: 键或索引

        Returns:
            对应的值
        """
        if isinstance(self._data, (dict, list)):
            return self._data[key]
        else:
            raise TypeError(f"'{type(self._data).__name__}' object is not subscriptable")

    def __setitem__(self, key: Union[str, int], value: Any) -> None:
        """
        支持通过索引访问设置数据（字典方式访问）

        Args:
            key: 键或索引
            value: 值
        """
        if isinstance(self._data, (dict, list)):
            self._data[key] = value
        else:
            raise TypeError(f"'{type(self._data).__name__}' object does not support item assignment")

    def __contains__(self, item: str) -> bool:
        """
        支持 in 操作符

        Args:
            item: 要检查的项

        Returns:
            是否包含该项
        """
        if isinstance(self._data, dict):
            return item in self._data
        elif isinstance(self._data, list):
            return item in self._data
        else:
            return False

    def __iter__(self) -> Iterator:
        """
        支持迭代

        Returns:
            迭代器
        """
        if isinstance(self._data, dict):
            return iter(self._data)
        elif isinstance(self._data, list):
            return iter(self._data)
        else:
            return iter([])

    def __len__(self) -> int:
        """
        支持 len() 函数

        Returns:
            数据长度
        """
        if isinstance(self._data, (dict, list)):
            return len(self._data)
        else:
            return 0

    def __repr__(self) -> str:
        """
        对象的字符串表示

        Returns:
            字符串表示
        """
        return f"{self.__class__.__name__}({repr(self._data)})"

    def __str__(self) -> str:
        """
        对象的字符串表示

        Returns:
            字符串表示
        """
        return json.dumps(self.to_dict(), ensure_ascii=False, indent=2)

    def to_dict(self) -> Dict[str, Any]:
        """
        将对象转换为字典

        Returns:
            字典表示
        """
        if isinstance(self._data, dict):
            result = {}
            for key, value in self._data.items():
                if isinstance(value, JsonObject):
                    result[key] = value.to_dict()
                elif isinstance(value, list):
                    result[key] = self._list_to_dict(value)
                else:
                    result[key] = value
            return result
        elif isinstance(self._data, list):
            return self._list_to_dict(self._data)
        else:
            # 对于非字典/列表类型，将其包装在字典中以保持一致性
            return {"value": self._data} if self._data is not None else {}

    def _list_to_dict(self, data_list: List[Any]) -> List[Any]:
        """
        将列表转换为字典表示

        Args:
            data_list: 列表数据

        Returns:
            转换后的列表
        """
        result = []
        for item in data_list:
            if isinstance(item, JsonObject):
                result.append(item.to_dict())
            elif isinstance(item, list):
                result.append(self._list_to_dict(item))
            else:
                result.append(item)
        return result

    def get(self, key: str, default: Any = None) -> Any:
        """
        获取属性值，支持默认值（字典方式访问）

        Args:
            key: 键
            default: 默认值

        Returns:
            属性值或默认值
        """
        if isinstance(self._data, dict) and key in self._data:
            return self._data[key]
        return default

    def keys(self) -> List[str]:
        """
        获取所有键（字典方式访问）

        Returns:
            键列表
        """
        if isinstance(self._data, dict):
            return list(self._data.keys())
        else:
            return []

    def values(self) -> List[Any]:
        """
        获取所有值（字典方式访问）

        Returns:
            值列表
        """
        if isinstance(self._data, dict):
            return list(self._data.values())
        else:
            return []

    def items(self) -> List[tuple]:
        """
        获取所有键值对（字典方式访问）

        Returns:
            键值对列表
        """
        if isinstance(self._data, dict):
            return list(self._data.items())
        else:
            return []


def load_json_object(file_path: str, encoding: str = 'utf-8') -> JsonObject:
    """
    从JSON文件加载数据并返回JsonObject实例

    Args:
        file_path: JSON文件路径
        encoding: 文件编码

    Returns:
        JsonObject实例
    """
    try:
        with open(file_path, 'r', encoding=encoding) as f:
            data = json.load(f)
        return JsonObject(data)
    except Exception as e:
        logger.error(f"加载JSON文件失败: {e}")
        return JsonObject({})


def loads_json_object(json_string: str) -> JsonObject:
    """
    从JSON字符串加载数据并返回JsonObject实例

    Args:
        json_string: JSON字符串

    Returns:
        JsonObject实例
    """
    try:
        data = json.loads(json_string)
        return JsonObject(data)
    except Exception as e:
        logger.error(f"解析JSON字符串失败: {e}")
        return JsonObject({})


def dumps_json_object(obj: JsonObject, indent: int = None) -> str:
    """
    将JsonObject实例转换为JSON字符串

    Args:
        obj: JsonObject实例
        indent: 缩进空格数

    Returns:
        JSON字符串
    """
    try:
        return json.dumps(obj.to_dict(), ensure_ascii=False, indent=indent)
    except Exception as e:
        logger.error(f"序列化JsonObject失败: {e}")
        return "{}"